(defun concat-numbers (n)
  (loop for i = 1 then (1+ i)
       for s = (write-to-string i) then (concatenate 'string s (write-to-string i))
       until  (> (length s) n)
       finally (return s)))

(defun nthd-naive(n)
  (parse-integer (string (char (concat-numbers n) (1- n)))))

(defun digits (n)
  (if (< n 10) 1
      (1+ (digits (floor (/ n 10))))))

(defun nth-from-left (n i)
  (if (or (zerop i) (< n 10)) (mod n 10)
      (nth-from-left (floor (/ n 10)) (1- i))))

(defun nthd (n)
  (loop for i = 1 then (1+ i)
       for s = (digits i) then (+ s (digits i))
       until (>= s n)
       finally (return (nth-from-left i (- s n)))))

(defun test-nthd(n)
  (= (nthd-naive n) (nthd n)))

(defun probl40()
  (reduce #'* (loop for i = 1 then (* 10 i) until (>= i 1000000) collect (nthd i))))
  
  
 ;    9 .. 1
;   90 .. 2
;  900 .. 3
; 9000 .. 4

(defun dnth-naive(poz)
  (loop for i = 0 then (1+ i)
     with s = ""
     until (> (length s) poz)
     do (setq s (concatenate 'string s (write-to-string i)))
     finally (return (parse-integer (string (char s poz))))))

(defun digits (n)
  (if (< n 10) 1
      (1+ (digits (floor (/ n 10))))))

(defun drop-first-digit(n)
  (if (< n 10) 0
      (+ (* 10 (drop-first-digit (floor (/ n 10)))) (mod n 10))))

(defun digit-from-left(i n)
  (if (<= (digits n) i)
      (mod n 10)
      (digit-from-left i (floor (/ n 10)))))
      

(defun dnth (n)
  (loop for i = 1 then (1+ i) 
     for count = 0 then (+ count (digits i))
     until (>= count n)
     when (>= (+ count (digits (1+ i))) n)
     do (print (digit-from-left (- n count) (1+ i)))))

(defun dnth-testp(n)
  (eq (dnth n) (dnth-naive n)))